/*
 * ===================================================================
 *  
 *      Filename:  log_client_backup.c
 *
 *   Description:  This file is used to backup the msg which can NOT be
 *                 sent to the server because of the network. The cached
 *                 msg will be flushed to the server once the network is
 *                 available.
 *
 *       Version:  1.0
 *        Create:  2010/07/13
 *
 *        Author:  Keven Zhu     kevenzhu@tencent.com
 *     Copyright:  Reserved by Tencent.com Co.ltd
 *          
 * ====================================================================
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "lib/util.h"
#include "log_client_api.h"

#define DEFAULT_BACKUP_PATH  "log.bak"
pthread_mutex_t backup_mutex;
#define BK_TRIGGER  1
#define BK_HANDLED  0
int backup_flag = 0;

int get_backup_status()
{
    return backup_flag;
}

int flush_backup_to_srv(int sockfd)
{
    char buff[MAX_LOG_MSG_SIZE];
    FILE *backup_file;

    pthread_mutex_lock(&backup_mutex);
    backup_file = fopen(DEFAULT_BACKUP_PATH,"r");
    if(!backup_file)
    {
        pthread_mutex_unlock(&backup_mutex);
        perror("faile to open the backup file for flushing");
        return INVIO;
    }
    /*we must read the file line by line ,otherwise the srv will crash!!!!  format is important*/
    while(fgets(buff+2,MAX_LOG_MSG_SIZE-2,backup_file))
    {
        /*do the basic checksum*/
        if(buff[2] == '+')
        {
            buff[2] = 1;
        }
        else if(buff[2] == '_')
        {
            buff[2] = 0;
        }
        else
        {
            continue;
        }
        *(short*)buff = 3+strlen(buff+3);
        /*we use the tcp socket to send the log msg*/
        if(-1 == send(sockfd,buff,*(short*)buff,0))
        {
            log_doctor(doctor_level,"failed to send the backup file to the server\n");
            return INVIO;
        }
    }
    /*remove the backup file now*/
    remove(DEFAULT_BACKUP_PATH);
    fclose(backup_file);
    backup_flag = BK_HANDLED;
    pthread_mutex_unlock(&backup_mutex);
    return NOERR;
}
/*translate the special character to the space*/
int translate_special_character(char* buff)
{
    int i = 3;
    /*we keep our's \n\0*/
    int ilen = *(short*)buff-2;
    /*replace the color bit*/
    if(buff[2])
    {
        buff[2] = '+';
    }
    else
    {
        buff[2] = '_';
    }
    /*32 means space, between 32 and 126 is readable*/
    while(i<ilen)
    {
        if(buff[i]>=32 &&buff[i] <= 126)
        {
            //continue;
        }
        else
        {
            buff[i] = 32;
        }
        i++;
    }
    return NOERR;
}

int send_log_to_backup(char* buff)
{
    int fd = 0;
    int ilen = *(short*)buff - 3;
    
    pthread_mutex_lock(&backup_mutex);
    fd = open(DEFAULT_BACKUP_PATH,O_APPEND|O_RDWR|O_CREAT,00666);
    if(fd == -1)
    {
        pthread_mutex_unlock(&backup_mutex);
        perror("failed to create the backup file");
        return INVIO;
    }
    backup_flag = BK_TRIGGER;
    /*translate the string to the readable character*/
    translate_special_character(buff);
    /*we only write the color to the file*/
    write(fd,buff+2,ilen);/*ignor the '\0' at the end of the line*/
    /*close the file handler*/
    close(fd);
    pthread_mutex_unlock(&backup_mutex);
    return NOERR;
}

int init_log_backup()
{
    if(pthread_mutex_init(&backup_mutex,NULL))
    {
        perror("failed to initialize the mutex for the backup");
        return INVIO;
    }
    return NOERR;
}

int finit_log_backup()
{
    pthread_mutex_destroy(&backup_mutex);
    return NOERR;
}
